/*!
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* global describe, test, expect, jest */

import React from "react";
import { render } from "@testing-library/react";
import moment from "moment-timezone";

import { TableWrapper } from "src/utils/testUtils";
import * as useGridDataModule from "src/api/useGridData";
import type { DagRun } from "src/types";

import DagRuns from "./index";

const datestring = new Date().toISOString();
const generateRuns = (length: number): DagRun[] =>
  [...Array(length)].map((_, i) => ({
    runId: `run-${i}`,
    dataIntervalStart: datestring,
    dataIntervalEnd: datestring,
    state: "success",
    runType: "manual",
    queuedAt: "2021-11-08T21:14:18.21521+00:00",
    startDate: "2021-11-08T21:14:19.704433+00:00",
    endDate: "2021-11-08T21:17:13.206426+00:00",
    lastSchedulingDecision: datestring,
    executionDate: datestring,
    externalTrigger: false,
    conf: null,
    confIsJson: false,
    note: "someRandomValue",
  }));

describe("Test DagRuns", () => {
  test("Durations and manual run arrow render correctly, but without any date ticks", () => {
    const dagRuns: DagRun[] = [
      {
        runId: "run1",
        dataIntervalStart: datestring,
        dataIntervalEnd: datestring,
        queuedAt: "2021-11-08T21:14:18.21521+00:00",
        startDate: "2021-11-08T21:14:19.704433+00:00",
        endDate: "2021-11-08T21:17:13.206426+00:00",
        state: "failed",
        runType: "scheduled",
        executionDate: "2021-11-08T21:14:19.704433+00:00",
        lastSchedulingDecision: datestring,
        externalTrigger: false,
        conf: null,
        confIsJson: false,
        note: "someRandomValue",
      },
      {
        runId: "run2",
        dataIntervalStart: datestring,
        dataIntervalEnd: datestring,
        state: "success",
        runType: "manual",
        queuedAt: "2021-11-08T21:14:18.21521+00:00",
        startDate: "2021-11-09T00:19:43.023200+00:00",
        endDate: "2021-11-09T00:22:18.607167+00:00",
        executionDate: "2021-11-08T21:14:19.704433+00:00",
        lastSchedulingDecision: datestring,
        externalTrigger: false,
        conf: null,
        confIsJson: false,
        note: "someRandomValue",
      },
    ];
    const data = {
      groups: {},
      dagRuns,
    };

    const spy = jest.spyOn(useGridDataModule, "default").mockImplementation(
      () =>
        ({
          data,
        } as any)
    );
    const { queryAllByTestId, getByText, queryByText } = render(<DagRuns />, {
      wrapper: TableWrapper,
    });

    expect(queryAllByTestId("run")).toHaveLength(2);
    expect(queryAllByTestId("manual-run")).toHaveLength(1);
    expect(getByText("00:02:53")).toBeInTheDocument();
    expect(getByText("00:01:26")).toBeInTheDocument();
    expect(
      queryByText(moment.utc(dagRuns[0].executionDate).format("MMM DD, HH:mm"))
    ).toBeNull();

    spy.mockRestore();
  });

  test("Top date ticks appear when there are 4 or more runs", () => {
    const data = {
      groups: {},
      dagRuns: generateRuns(4),
    };
    const spy = jest.spyOn(useGridDataModule, "default").mockImplementation(
      () =>
        ({
          data,
        } as any)
    );
    const { getByText } = render(<DagRuns />, { wrapper: TableWrapper });
    expect(
      getByText(moment.utc(datestring).format("MMM DD, HH:mm"))
    ).toBeInTheDocument();
    spy.mockRestore();
  });

  test("Show 1 date tick when there are less than 14 runs", () => {
    const data = {
      groups: {},
      dagRuns: generateRuns(11),
    };
    const spy = jest.spyOn(useGridDataModule, "default").mockImplementation(
      () =>
        ({
          data,
        } as any)
    );
    const { queryAllByText } = render(<DagRuns />, { wrapper: TableWrapper });
    expect(
      queryAllByText(moment.utc(datestring).format("MMM DD, HH:mm"))
    ).toHaveLength(1);
    spy.mockRestore();
  });

  test("Show 2 date ticks when there are 14+ runs", () => {
    const data = {
      groups: {},
      dagRuns: generateRuns(14),
    };
    const spy = jest.spyOn(useGridDataModule, "default").mockImplementation(
      () =>
        ({
          data,
        } as any)
    );
    const { queryAllByText } = render(<DagRuns />, { wrapper: TableWrapper });
    expect(
      queryAllByText(moment.utc(datestring).format("MMM DD, HH:mm"))
    ).toHaveLength(2);
    spy.mockRestore();
  });

  test("Handles empty data correctly", () => {
    const spy = jest.spyOn(useGridDataModule, "default").mockImplementation(
      () =>
        ({
          data: { groups: {}, dagRuns: [] },
        } as any)
    );

    const { queryByTestId } = render(<DagRuns />, { wrapper: TableWrapper });
    expect(queryByTestId("run")).toBeNull();

    spy.mockRestore();
  });
});
